/******************************************************************************
*	UART of CC2541
*	by longcd
*
*	release : 2018/10/10,UART0 TX,RX(interrupt) test OK
*******************************************************************************
*/

#include <ioCC2541.h>

//type define
#if 1
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
#endif

#include "CC2541_UART.h"

/*	init UART0 I/O
 *
 *	P02 --- RX,P03 --- TX,when Alt = 1
 */
void UART0_IO_init(void)
{
	//USART 0 I/O location Alternative 1
	PERCFG &= ~1U;

	//P02,P03 as Peripheral function
	P0SEL |= ((1u << 2) | (1u << 3));

	//P02 as input
	P0DIR &= ~(1u << 2);

	//P03 as output
	P0DIR |= (1u << 3);
}

/*	UART0 interrupt init
 */
void UART0_IT_init(void)
{
	TCON &= ~URX0IF;	//clear USART 0 RX interrupt flag
	IEN0 |=  URX0IE;	//USART0 RX interrupt enable
}

/*	init UART0
 *
 *	dataBits : can be DATA_8BIT or DATA_9BIT
 *	stopBits : can be STOP_BITS_1 or STOP_BITS_2
 *	baudrate : only test 9600,115200
 */
void UART0_Init(uint8 dataBits,uint8 stopBits,uint32 baudrate)
{
	UART0_IO_init();
	UART0_IT_init();

	//UART mode
	U0CSR = UART_MODE;

	//disable parity,stop-bit high,start-bit low
	U0UCR = PARITY_DISABLE | STOP_LEVEL_HIGH | START_LEVEL_LOW;

	//set dataBits,stopBits
	U0UCR |= (dataBits | stopBits);

	//LSB first
	U0GCR = LSB_FIRST;

	switch(baudrate){
		case 9600:
			U0GCR |= 8;
			U0BAUD = 59;
			break;

		case 115200:
			U0GCR |= 11;
			U0BAUD = 216;
			break;

		default:
			U0GCR |= 8;
			U0BAUD = 59;
			break;
	}

	//Receiver enabled
	U0CSR |= RX_ENABLE;
}

/*	UART0 transmit byte
 */
void UART0_TransmitByte(uint8 Data)
{
	U0DBUF = Data;
	while((U0CSR & TX_BYTE) != TX_BYTE);	//wait data transmitted
	U0CSR &= ~TX_BYTE;		//clear flag
}

/*	UART0 RX interrupt function
 */
#pragma vector = URX0_VECTOR
__interrupt void UART0_RX_Handler(void)
{
	//Interrupt pending flag cleared by hardware

	UART0_RX_callback(U0DBUF);
}

